package app1.rapidsquare.com.database;

import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.util.ArrayList;

import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.params.BasicHttpParams;
import org.apache.http.params.HttpConnectionParams;
import org.apache.http.params.HttpParams;
import org.json.JSONArray;
import org.json.JSONObject;

import app1.rapidsquare.com.Utility.Utility;
import app1.rapidsquare.com.classes.AgileClass;

import android.content.Context;

public abstract class AgileSyncHelper<T extends AgileClass> {
    private String url;
    protected HttpEntity httpEntity;
    protected Context mContext;
    private AgileSqliteHelper mSqliteHelper;
    Class<T> mClass;

    public AgileSyncHelper(Context context, Class<T> clazz) {
        this.mContext = context;
        mSqliteHelper = new AgileSqliteHelper(mContext);
        mClass = clazz;

    }

    protected String getUserToken() {
        return Utility.getUserSession(mContext).UserToken;
    }

    protected int getUserId() {
        return Utility.getUserSession(mContext).Id;
    }

    protected AgileSqliteHelper getSqliteHelper() {
        if (this.mSqliteHelper == null)
            this.mSqliteHelper = new AgileSqliteHelper(mContext);
        return this.mSqliteHelper;
    }

    protected String getURL() {
        return this.url;
    }

    protected void setURL(String url) {
        this.url = url;
    }

    protected synchronized void RunSync() {

        try {
            String result = "";
            HttpParams httpParams = new BasicHttpParams();
            HttpConnectionParams.setConnectionTimeout(httpParams, 5000);

            HttpConnectionParams.setSoTimeout(httpParams, 5000);

            HttpClient httpclient = Utility.getHttpClient();
            //HttpClient httpclient = new DefaultHttpClient(httpParams);

            HttpPost httppost = new HttpPost(getURL());

            httppost.addHeader("Accept", "application/json");
            httppost.addHeader("Content-type", "application/json");


            httppost.setEntity(httpEntity);

            HttpResponse response = httpclient.execute(httppost);
            HttpEntity entity = response.getEntity();

            BufferedReader reader = new BufferedReader(new InputStreamReader(
                    entity.getContent(), "UTF-8"));
            result = reader.readLine();
            reader.close();
            DeserializeData(result);

        } catch (Exception ex) {
            Utility.Log("AgileSyncHelper -> RunSync ", ex);
        }

    }

    private synchronized void DeserializeData(String result) {
        ArrayList<T> resultList = new ArrayList<T>();
        if (!Utility.isNullOrEmpty(result)) {
            try {
                JSONObject jObject = new JSONObject(result);
                if (jObject.has("Result")) {
                    JSONArray jsonArray = new JSONArray();
                    String jsonResult = jObject.getString("Result");
                    if (!Utility.isNullOrEmpty(jsonResult) && !jsonResult.equals("null")) {
                        if (jsonResult.contains("[")) {
                            jsonArray = new JSONArray(jsonResult);
                        } else {
                            JSONObject jsonObject = new JSONObject(jsonResult);
                            jsonArray.put(jsonObject);
                        }
                    }

                    for (int i = 0; i < jsonArray.length(); i++) {
                        JSONObject jsonObject = (JSONObject) jsonArray.get(i);
                        T value = (T) Utility.Deserialize(mClass, jsonObject.toString());
                        resultList.add(value);
                    }

                    UpdateData(resultList);
                }

            } catch (Exception e) {
                Utility.Log("AgileSyncHelper -> DeserializeData ", e);
            }
        }

        Delete();

        Vacuum();

    }

    protected abstract void UpdateData(ArrayList<T> resultList);

    protected abstract void Delete();

    private void Vacuum() {
        try {
            if (this.mSqliteHelper != null)
                this.mSqliteHelper.getReadableDatabase().execSQL("vacuum");
        }
        catch (Exception ex)
        {
            Utility.Log("AgileSyncHelper -> Vacuum",ex);
        }
    }
}
